home *** CD-ROM | disk | FTP | other *** search
/ Shareware Grab Bag / Shareware Grab Bag.iso / 007 / vtkerma1.arc / MSCOMM.ASM < prev    next >
Assembly Source File  |  1986-02-13  |  19KB  |  676 lines

  1.     PAGE 59, 132
  2.  
  3.     TITLE MSCOMM -- Module to handle all packet communications
  4.  
  5. ; Update 2 Jan 86
  6.  
  7. IF1
  8.  %OUT >> Starting pass 1
  9. ELSE
  10.  %OUT >> Starting pass 2
  11. ENDIF
  12.  
  13.     public    data, spack, rpack, portval, port1, port2, hierr
  14.     PUBLIC Data_2
  15.  
  16.     include msdefs.h
  17.  
  18. gettim    equ    2CH        ; Get the time of day. 
  19. maxlp    equ    500        ; Use as number of times to loop (in inchr).
  20. true    equ    1
  21. false    equ    0
  22. mntrgl    equ    bufsiz/4    ; Low point = 1/4 of the way full.
  23. maxpack    equ    60H        ; largest packet we can handle
  24.  
  25. DataS    SEGMENT    PUBLIC 'DataS'
  26.  
  27.     EXTRN Flags:byte, trans:byte, pack:byte, count:word, xofsnt:byte
  28.  
  29.     EVEN
  30.  
  31. temp    dw    0
  32. pktptr  dw    ?        ; Position in receive packet.
  33. incnt    dw    ?        ; Number of chars read in from port.
  34. loopct    dw    ?        ; Loop counter.
  35. time     dw    ?        ; When we should timeout. 
  36.     dw    ?        ; Want a double word
  37. portval    dw    port1        ; Default is to use port 1.
  38.  
  39. crctab    dw    00000H
  40.     dw    01081H
  41.     dw    02102H
  42.     dw    03183H
  43.     dw    04204H
  44.     dw    05285H
  45.     dw    06306H
  46.     dw    07387H
  47.     dw    08408H
  48.     dw    09489H
  49.     dw    0A50AH
  50.     dw    0B58BH
  51.     dw    0C60CH
  52.     dw    0D68DH
  53.     dw    0E70EH
  54.     dw    0F78FH
  55.  
  56. crctb2    dw    00000H
  57.     dw    01189H
  58.     dw    02312H
  59.     dw    0329BH
  60.     dw    04624H
  61.     dw    057ADH
  62.     dw    06536H
  63.     dw    074BFH
  64.     dw    08C48H
  65.     dw    09DC1H
  66.     dw    0AF5AH
  67.     dw    0BED3H
  68.     dw    0CA6CH
  69.     dw    0DBE5H
  70.     dw    0E97EH
  71.     dw    0F8F7H
  72.  
  73. port1    prtinfo    <0FFFH,floxon,0,defpar,1,0,defhand>
  74. port2    prtinfo    <0FFFH,floxon,0,defpar,1,0,defhand>
  75.  
  76. hierr    db    0        ; Non-ascii char (non-zero if yes).
  77. spmes    db    'Spack:  $'
  78. rpmes     db    'Rpack:  $'
  79. crlf    db      cr,lf,'$'
  80. CtrlEMsg db    'Protocol aborted with ^E$'
  81. cemsg    db    'Remote BTLink: Protocol aborted with ^E$'
  82. tmp    db    ?,'$'
  83. packet  db    ?,?,?,?        ; Packet (data is part of it).
  84. data    db    5AH DUP(?)    ; Data and checksum field of packet.
  85. Data_2    DB    5Ah DUP(?)    ; Place to copy data to
  86. recpkt  db    maxpack DUP(?)    ; Receive packet storage (use the following).
  87.  
  88. DataS    ENDS
  89.  
  90. Code    SEGMENT    PUBLIC
  91.  
  92.     extrn    prtchr:near, clrbuf:near, outchr:near
  93.     extrn    sppos:near, biterr:near, intmsg:near
  94.     extrn    clearl:near, rppos:near, errpack:near
  95.     EXTRN Say_aborted:NEAR, Show_warning:NEAR, Beep:NEAR
  96.  
  97.     assume     cs:code, ds:datas
  98.  
  99. ;    Packet routines
  100.  
  101. ; Send_Packet
  102. ; This routine assembles a packet from the arguments given and sends it
  103. ; to the host.
  104. ;
  105. ; Expects the following:
  106. ;    AH     - Type of packet (D,Y,N,S,R,E,F,Z,T)
  107. ;    ARGBLK - Packet sequence number
  108. ;    ARGBK1 - Number of data characters
  109. ; Returns: +1 always
  110.  
  111. SPKT    PROC    NEAR
  112.  
  113. spack:     push ax            ; Save the packet type.
  114.     call clrbuf        ; Clear the input buffer. [20e]
  115.     mov bx,offset packet    ; Get address of the send packet.
  116.     mov ah,trans.ssoh    ; Get the start of header char.
  117.     mov [bx],ah        ; Put in the packet.
  118.     inc bx            ; Point to next char.
  119.     mov ax,pack.argbk1    ; Get the number of data chars.
  120.     xchg ah,al
  121.     mov al,trans.chklen    ; Length of checksum.
  122.     dec al            ; Extra length of checksum.
  123.     add ah,' '+3        ; Real packet character count made printable.
  124.     add ah,al        ; Account for checksum length in count.
  125.     mov [bx],ah        ; Put in the packet.
  126.     inc bx            ; Point to next char.
  127.     mov ch,0        ; For the 16 bit checksum.
  128.     mov cl,ah        ; Start the checksum.
  129.     mov ax,pack.argblk    ; Get the packet number.
  130.     add al,' '        ; Add a space so the number is printable.
  131.     mov [bx],al        ; Put in the packet.
  132.     inc bx            ; Point to next char.
  133.     add cx,ax        ; Add the packet number to the checksum.
  134.     pop ax            ; Get the packet type.
  135.     mov [bx],ah        ; Put in the packet.
  136.     inc bx            ; Point to next char.
  137.     mov al,0
  138.     xchg ah,al
  139.     add cx,ax        ; Add the type to the checksum.
  140.     mov dx,pack.argbk1    ; Get the packet size.
  141. spack2: cmp dx,0        ; Are there any chars of data?
  142.      jz spack3        ;  No, finish up.
  143.     dec dx            ; Decrement the char count.
  144.     mov al,[bx]        ; Get the next char.
  145.     inc bx            ; Point to next char.
  146.     mov ah,0
  147.     add cx,ax        ; Add the char to the checksum.
  148.     cmp al,0
  149.     jns spack2
  150.     cmp hierr,0ffH        ; Printed message already?
  151.     je spack2        ; Yes, then that's it.
  152.     push bx
  153.     push cx
  154.     push dx
  155.     call biterr
  156.     pop dx
  157.     pop cx
  158.     pop bx
  159.     mov hierr,0FFH        ; set err flag. 
  160.     jmp spack2        ; Go try again.
  161. spack3:    cmp trans.chklen,2    ; What kind of checksum are we using.
  162.     je spackx        ; 2 characters.
  163.     jg spacky        ; 3 characters.
  164.     mov ah,cl        ; 1 char: get the character total.
  165.     mov ch,cl        ; Save here too (need 'cl' for shift).
  166.     and ah,0C0H        ; Turn off all but the two high order bits.
  167.     mov cl,6
  168.     shr ah,cl        ; Shift them into the low order position.
  169.     mov cl,ch
  170.     add ah,cl        ; Add it to the old bits.
  171.     and ah,3FH        ; Turn off the two high order bits.  (MOD 64)
  172.     add ah,' '        ; Add a space so the number is printable.
  173.     mov [bx],ah        ; Put in the packet.
  174.     inc bx            ; Point to next char.
  175.     jmp spackz        ; Add EOL char.
  176. spacky:    mov al,0        ; Get a null.
  177.     mov [bx],al        ; To determine end of buffer.
  178.     push bx            ; Don't lose our place.
  179.     mov bx,offset packet+1    ; First checksummed character.
  180.     call crcclc        ; Calculate the CRC.
  181.     pop bx
  182.     push cx
  183.     mov ax,cx        ; Manipulate it here.
  184.     and ax,0F000H        ; Get 4 highest bits.
  185.     mov cl,4
  186.     shr ah,cl        ; Shift them over 4 bits.
  187.     add ah,' '        ; Make printable.
  188.     mov [bx],ah        ; Add to buffer.
  189.     inc bx
  190.     pop cx            ; Get back checksum value.
  191. spackx:    push cx            ; Save it for now.
  192.     and cx,0FC0H        ; Get bits 6-11.
  193.     mov ax,cx
  194.     mov cl,6
  195.     shr ax,cl        ; Shift them bits over.
  196.     add al,' '        ; Make printable.
  197.     mov [bx],al        ; Add to buffer.
  198.     inc bx
  199.     pop cx            ; Get back the original.
  200.     and cx,003FH        ; Get bits 0-5.
  201.     add cl,' '        ; Make printable.
  202.     mov [bx],cl        ; Add to buffer.
  203.     inc bx
  204. spackz:    mov ah,trans.seol    ; Get the EOL the other host wants.
  205.     mov [bx],ah        ; Put in the packet.
  206.     inc bx            ; Point to next char.
  207.     mov ah,0        ; Get a null.
  208.     mov [bx],ah        ; Put in the packet.
  209.     cmp flags.debug,0    ; debug mode.
  210.     je spack4
  211.     inc bx
  212.     mov ah,'$'
  213.     mov [bx],ah
  214.     call sppos
  215.     call clearl        ; Clear to end of line.
  216.     mov dx,offset crlf
  217.     mov ah,prstr
  218.     int dos
  219.     call clearl        ; Next line too.
  220.     call sppos        ; Reposition cursor.
  221.     mov ah,prstr
  222.     mov dx,offset spmes
  223.     int dos
  224.     mov dx,offset packet
  225.     mov ah,prstr
  226.     int dos            ; debug end.
  227. spack4: call outpkt        ; Call the system dependent routine.
  228.      jmp r
  229.     jmp rskp
  230. SPKT    ENDP 
  231.  
  232.  
  233. ;    Write out a packet
  234.  
  235. OUTPKT  PROC
  236.  
  237.     mov dh,trans.spad    ; Get the number of padding chars.
  238.  
  239. outpk2: dec dh
  240.     cmp dh,0
  241.     jl outpk3        ; If none left proceed.
  242.     mov ah,trans.spadch    ; Get the padding char.
  243.     call outchr        ; Output it.
  244.      jmp r            ; Say we failed. [25]
  245.  
  246.     jmp outpk2
  247.  
  248. outpk3: mov bx,offset packet    ; Point to the packet.
  249.  
  250. outlup: mov ah,[bx]        ; Get the next character.
  251.     cmp ah,0        ; Is it a null?
  252.     jnz outlp2
  253.     jmp rskp
  254.  
  255. outlp2: call outchr        ; Output the character.
  256.      jmp r
  257.     inc bx            ; Increment the char pointer.
  258.     jmp outlup
  259.  
  260. OUTPKT  ENDP
  261.  
  262.  
  263. ; Calculate the CRC.  Returns the CRC in CX.  Destroys: BX, AX.
  264. crcclc:    push dx
  265.     push si
  266.     mov dx,0        ; Initial CRC value is 0.
  267. crc0:    mov al,[bx]        ; Get the first char of the string.
  268.     cmp al,0        ; If null, then we're done.
  269.     je crc1
  270.     inc bx
  271.     xor al,dl        ; Xor input with lo order byte of CRC.
  272.     mov ah,al        ; Get a copy.
  273.     and ah,0F0H        ; Get hi 4 bits.
  274.     mov cl,4
  275.     shr ah,cl        ; Right justify.
  276.     and al,0FH        ; Get lo 4 bits.
  277.     push bx
  278.     mov si,offset crctb2    ; Low portion of CRC factor.
  279.     mov bh,0
  280.     mov bl,al
  281.     add bl,al        ; Get word index.
  282.     mov cx,[si+bx]        ; Low portion.
  283.     mov si,offset crctab    ; High portion of CRC factor.
  284.     mov bh,0
  285.     mov bl,ah
  286.     add bl,ah        ; Get word index.
  287.     mov bx,[si+bx]
  288.     xor bx,cx        ; Add the two.
  289.     mov cl,8
  290.     shr dx,cl        ; Shift CRC 8 bits to the right.
  291.     xor dx,bx        ; XOR table value and CRC.
  292.     pop bx            ; Retrieve index.
  293.     jmp crc0
  294. crc1:    mov cx,dx        ; Return it in CX.
  295.     pop si
  296.     pop dx
  297.     ret
  298.  
  299. ; Receive_Packet
  300. ; This routine waits for a packet arrive from the host.  It reads
  301. ; chars until it finds a SOH.
  302.  
  303. RPACK    PROC
  304.  
  305.     call inpkt        ; Read up to a carriage return.
  306.      jmp r            ;  Return bad.
  307.  
  308. rpack0: call getchr        ; Get a character.
  309.      jmp SHORT RPack    ;  No SOH in this "packet", try the next [tm]
  310.      nop            ;  Make it 3 bytes long
  311.  
  312. ;     jmp r            ;  Hit the carriage return, return bad.
  313.  
  314.     cmp al,trans.rsoh    ; Is the char the start of header char?
  315.      jne rpack0        ;  No, go until it is.
  316.  
  317. rpack1: call getchr        ; Get a character.
  318.      jmp r            ;  Hit the carriage return, return bad.
  319.     cmp al,trans.rsoh    ; Is the char the start of header char?
  320.      jz rpack1        ;  Yes, then go start over.
  321.     mov ch,0        ; For 16-bit checksum.
  322.     mov cl,al        ; Start the checksum.
  323.     mov ah,0
  324.     mov pack.argbk1,ax    ; Save the data count.
  325.     call getchr        ; Get a character.
  326.      jmp r            ;  Hit the carriage return, return bad.
  327.     cmp al,trans.rsoh    ; Is the char the start of header char?
  328.      jz rpack1        ;  Yes, then go start over.
  329.     mov ah,0
  330.     add cx,ax        ; Add it to the checksum.
  331.     sub al,' '        ; Get the real packet number.
  332.     mov ah,0
  333.     mov pack.argblk,ax    ; Save the packet number.
  334.     call getchr        ; Get a character.
  335.      jmp r            ;  Hit the carriage return, return bad.
  336.     cmp al,trans.rsoh    ; Is the char the start of header char?
  337.      jz rpack1        ;  Yes, then go start over.
  338.     mov ah,0
  339.     mov temp,ax        ; Save the message type. [11]
  340.     add cx,ax        ; Add it to the checksum.
  341.  
  342.  %OUT >> About half way through source file
  343.  
  344. ; Start of change.
  345. ; Now determine block check type for this packet.  Here we violate the layered
  346. ; nature of the protocol by inspecting the packet type in order to detect when
  347. ; the two sides get out of sync.  Two heuristics allow us to resync here:
  348. ;   a. An S packet always has a type 1 checksum.
  349. ;   b. A NAK never contains data, so its block check type is LEN-2. 
  350.     push cx
  351.     mov cl,al
  352.     mov ax,pack.argbk1    ; Get back the size.
  353.     sub al,34        ; unchar(len) - 2, for SEQ & TYPE fields.
  354.     mov ah,trans.chklen    ; Checksum length we expect.
  355.     cmp cl,'S'        ; Is this an "S" packet?
  356.     jne rpk0        ; Nope.
  357.     mov ah,1        ; Yes, use 1 char checksum.
  358. rpk0:    cmp cl,'N'        ; Is this a NAK?
  359.     jne rpk1        ; Nope.
  360.     mov ah,al        ; So, len - 2 is checksum type.
  361. rpk1:    mov trans.chklen,ah    ; Then, this is the chksum length.
  362.     sub al,ah        ; Real size of data.
  363.     mov dh,al        ; Need it here.
  364.     mov ah,0
  365.     mov pack.argbk1,ax    ; And here.
  366.     pop cx    
  367. ; End of change.
  368.     mov bx,offset data    ; Point to the data buffer.
  369. rpack2: dec dh            ; Any data characters?
  370.      js rpack3        ;  If not go get the checksum.
  371.     call getchr        ; Get a character.
  372.      jmp r            ;  Hit the carriage return, return bad.
  373.     cmp al,trans.rsoh    ; Is the char the start of header char?
  374.      jz rpack1        ;  Yes, then go start over.
  375.     mov [bx],al        ; Put the char into the packet.
  376.     inc bx            ; Point to the next character.
  377.     mov ah,0
  378.     add cx,ax        ; Add it to the checksum.
  379.     jmp rpack2        ; Go get another.
  380. rpack3: call getchr        ; Get a character.
  381.      jmp r            ;  Hit the carriage return, return bad.
  382.     cmp al,trans.rsoh    ; Is the char the start of header char?
  383.      jnz rpk3x
  384.      jmp rpack1        ;  Yes, then go start over.
  385. rpk3x:    sub al,' '        ; Turn the char back into a number.
  386.     cmp trans.chklen,2    ; What checksum length is in use.
  387.     je rpackx        ; Two character checksum.
  388.     jg rpacky        ; Three character CRC.
  389.     mov dh,cl        ; 1 char - get the character total.
  390.     and dh,0C0H        ; Turn off all but the two high order bits.
  391.     mov ch,cl
  392.     mov cl,6
  393.     shr dh,cl        ; Shift them into the low order position.
  394.     mov cl,ch
  395.     add dh,cl        ; Add it to the old bits.
  396.     and dh,3FH        ; Turn off the two high order bits.  (MOD 64)
  397.     cmp dh,al        ; Are they equal?
  398.      jz rpack4        ; If so finish up.
  399.     jmp rpack6        ; No, we fail.
  400. rpacky:    mov tmp,al        ; Save value from packet here.
  401.     mov ah,0        ; Three character CRC.
  402.     push bx
  403.     mov bx,pktptr        ; Where we are in the packet.
  404.     dec bx
  405.     mov [bx],ah        ; Add null to signify end of buffer.
  406.     mov bx,offset recpkt+1    ; Where data for CRC is.
  407.     call crcclc        ; Calculate the CRC and put into CX.
  408.     pop bx
  409.     push cx
  410.     mov ax,cx        ; Manipulate it here.
  411.     and ax,0F000H        ; Get 4 highest bits.
  412.     mov cl,4
  413.     shr ah,cl        ; Shift them over 4 bits.
  414.     pop cx            ; Get back checksum value.
  415.     cmp ah,tmp        ; Is what we got == what we calculated?
  416.     jne rpack6
  417.     call getchr        ; Get next character of checsum.
  418.      jmp r            ; Failed.    
  419.     cmp al,trans.rsoh    ; Restarting?
  420.      jz rpack7
  421.     sub al,' '        ; Get back real value.
  422. rpackx:    mov tmp,al        ; Save here for now.
  423.     push cx            ; Two character checksum.
  424.     and cx,0FC0H        ; Get bits 6-11.
  425.     mov ax,cx
  426.     mov cl,6
  427.     shr ax,cl        ; Shift them bits over.
  428.     pop cx            ; Get back the original.
  429.     cmp al,tmp        ; Are they equal?
  430.      jne rpack6        ; No, we fail.
  431.     call getchr        ; Get last character of checsum.
  432.      jmp r            ; Failed.    
  433.     cmp al,trans.rsoh    ; Restarting?
  434.      jz rpack7
  435.     sub al,' '        ; Get back real value.    
  436.     and cx,003FH        ; Get bits 0-5.
  437.     cmp al,cl        ; Do the last chars match?
  438.     jne rpack6
  439. rpack4: mov ah,0
  440.     mov [bx],ah        ; Put a null at the end of the data.
  441.     mov ax,temp        ; Get the type.   [11]
  442.     xchg al,ah        ; Packet type should be in AH.
  443.     jmp rskp
  444. rpack6:    ret
  445. rpack7:    jmp rpack1        ; For the jump out of range.
  446. RPACK    ENDP
  447.  
  448.  
  449.     PUBLIC INPKT, INCHR
  450.  
  451. INPKT    PROC
  452.  
  453.     mov bl,flags.cxzflg    ; Remember original value. [20b]
  454.     mov tmp,bl        ; Store it here. [20b]
  455.  
  456. inpkt1:    mov bx,offset recpkt    ; Point to the beginning of the packet.
  457.     mov incnt,0
  458.  
  459.     cmp flags.timflg,0    ; Are timeouts turned off.
  460.      je inpkt2        ; Yes, so skip this stuff.
  461.     cmp trans.stime,0    ; Don't time out?
  462.      je inpkt2        ; Yes, so skip this stuff.
  463.  
  464.     mov loopct,0        ; Use to check for timeout.
  465.     mov ah,gettim        ; Get the time.
  466.     int dos
  467.  
  468.     mov time,cx        ; Save hours:minutes
  469.     mov time+2,dx        ; Save seconds:hundreths
  470.     mov al,trans.stime    ; Timeout when getting data
  471.     add BYTE PTR time+3, al    ; If get to this time, then timeout
  472.     cmp BYTE PTR time+3, 59    ; Seconds over flow?
  473.      jle inpkt2        ;  No     
  474.  
  475.     inc BYTE PTR time    ; Bump the minutes
  476.     sub BYTE PTR time+3, 60    ; Pull back the seconds
  477.  
  478. inpkt2:    call inchr        ; Get a character.
  479.      jmp SHORT inpkt8    ;  Return failure. [20b]
  480.      nop            ;  Make it three bytes long. [20b] 
  481.  
  482.     mov [bx],ah        ; Put the char in the packet.
  483.     inc bx
  484.     inc incnt
  485.     cmp ah,trans.reol    ; Is it the EOL char?
  486.     je inpkt3        ; ended by eol, keep going
  487.     cmp incnt,maxpack    ; is it too big?
  488.     jbe inpkt2        ; no, keep going
  489.     jmp inpkt1        ; else just start over
  490. inpkt3:    cmp incnt,1        ; Ignore bare CR.   [2 start]
  491.     je inpkt1
  492.     mov bp,portval
  493.     cmp ds:[bp].hndflg,0    ; Waiting for handshake?
  494.     jz inpkt5        ; If not then proceed.
  495. inpkt4: call inchr        ; Wait for the turn around char.
  496.      jmp inpkt8        ;  Return failure. [20b]
  497.      nop            ;  Make it three bytes long.  [20b]
  498.     mov bp,portval
  499.     cmp ah,ds:[bp].hands    ; Is it the IBM turn around character?
  500.     jne inpkt4        ; If not, go until it is.
  501. inpkt5:    cmp flags.debug,0    ; In debug mode?
  502.     je inpkt6
  503.     mov ah,'$'
  504.     mov [bx],ah
  505.     call rppos
  506.     call clearl        ; Clear to end of line.
  507.     mov dx,offset crlf
  508.     mov ah,prstr
  509.     int dos
  510.     call clearl        ; Next line too.
  511.     call rppos        ; Reposition cursor.
  512.     mov ah,prstr
  513.     mov dx,offset rpmes
  514.     int dos
  515.     mov dx,offset recpkt
  516.     mov ah,prstr
  517.     int dos            ; debug end.
  518. inpkt6:    mov bx,offset recpkt
  519.     mov pktptr,bx        ; Save the packet pointer.
  520.  
  521.     mov bl,tmp        ; Get the original value. [20b]
  522.     cmp bl,flags.cxzflg    ; Did ^X/^Z flag change? [20b]
  523.      je inpkt7        ;  No
  524.  
  525.     call inpkt8        ; Use our own "error" handler
  526.  
  527. inpkt7:    jmp RSkp        ; Exit cleanly
  528.  
  529. inpkt8:    cmp flags.cxzflg,'C'    ; Did the user type a ^C? [25]
  530.     jne inpkt9
  531.     mov pack.state,'A'
  532.     jmp Say_aborted        ; Make noise and onscreen message, ret
  533.  
  534. inpkt9:    cmp flags.cxzflg,'E'    ; How about ^E?
  535.     jne inpk10        ; No just go on.
  536.     mov pack.state,'A'    ; Aborting
  537.     mov dx, OFFSET CtrlEMsg ; Message about ^E
  538.     call Show_warning    ; Display it
  539.     mov bx,offset cemsg    ; Message for error packet.
  540.     jmp errpack        ; Send an error packet, ret from there
  541.  
  542. inpk10:    mov bl,tmp        ; Get the original value. [20b]
  543.     cmp bl,flags.cxzflg    ; Did ^X/^Z flag change? [20b]
  544.     je inpk11        ; If not, just return failure.  [20b]
  545.  
  546.     call intmsg         ; Else, say we saw the interrupt. [20b]
  547.  
  548. inpk11:    ret
  549.  
  550. INPKT    ENDP
  551.  
  552.  
  553. ; Get a character, or a keyboard interrupt, or a potential timeout
  554.  
  555. INCHR    PROC
  556.  
  557.     call prtchr        ; Is there a character to read?
  558.      jmp inchr6        ; Got one.
  559.  
  560.     mov dl,0FFH        ; To read in a char.
  561.     mov ah,dconio        ; Is a char on the console?
  562.     int dos
  563.     jz inchr2        ; If not go look for another char.
  564.     mov ah,al 
  565.     cmp ah,cr        ; Is it a carriage return?
  566.     je inchr5        ; If yes, then leave.
  567.     add ah,100q        ; Make it printable. [25]
  568.     cmp ah,'Z'        ; Control-Z? [20b]
  569.      je inchr1        ; Yes - flag it. [20b]
  570.     cmp ah,'X'        ; Control-X? [20b]
  571.      je inchr1        ; Yes - flag it. [20b]
  572.     cmp ah,'E'        ; Control-E?
  573.      je inchr1        ; Flag it and get rest of packet.
  574.     cmp ah,'C'        ; Control-C? [25]
  575.      jne inchrNG        ;  No, go complain
  576.  
  577.     mov flags.cxzflg,ah    ; Save it. [25]
  578.     ret            ; Return right away. [25]
  579.  
  580. inchr1:    mov flags.cxzflg,ah    ; Remember what we saw. [20b]
  581.     jmp SHORT inchr2    ; Continue getting input. [20b]
  582.  
  583. inchrNG: call Beep        ; Some other character -- just beep
  584.  
  585. inchr2:    cmp flags.timflg,0    ; Are timeouts turned off?
  586.      je inchr        ; Yes, just check for more input.
  587.     cmp trans.stime,0    ; Doing time outs?
  588.      je inchr        ; No, just go check for more input.
  589.  
  590.     inc loopct
  591.     cmp loopct,maxlp    ; Times to go without checking time
  592.      jl inchr        ;  Don't check yet
  593.  
  594.     mov ah,gettim        ; Get the current time.
  595.     int dos
  596.  
  597.     cmp cx, time        ; Check hours and minutes.
  598.      jg inchr5        ; Over the limit so fail.
  599.      jl inchr3        ; Under the limit, keep going.
  600.  
  601.     cmp dx, time+2        ; Else, check seconds and hundreds of seconds.
  602.      jg inchr5        ; Return failure.
  603.  
  604. inchr3:    mov loopct,0        ; Reset counter.
  605.     jmp inchr        ; Try a bunch more times
  606.  
  607. inchr5:    ret            ; Done here
  608.  
  609.  
  610. ; We have a character from the port
  611.  
  612. inchr6: mov ah,al
  613.     mov bp,portval        ; Point to current port structure.
  614.     cmp ds:[bp].parflg,parnon    ; Is the parity none?    [10]
  615.     je inchr7        ; We're done.        [10]
  616.     and ah,7FH        ; Turn off the parity bit.
  617. inchr7:    cmp ds:[bp].floflg,0    ; Doing any flow control?
  618.     jne inchr8        ; Yes, check it out.
  619.     jmp rskp        ; No, just return the data.
  620. inchr8:    cmp xofsnt,true        ; Have we sent flow char (XOFF)?
  621.     je inchr9        ; Yes.
  622.     jmp rskp        ; No, just return.
  623. inchr9:    cmp count,mntrgl    ; Under the low trigger point?
  624.     jb inchra        ; Yes.
  625.     jmp rskp        ; No, just return.
  626. inchra:    push ax
  627.     mov bp,portval
  628.     mov ax,ds:[bp].flowc    ; Get flow control char (AH = XON, AL = XOFF).
  629.     call outchr        ; Send it (XON).
  630.     mov xofsnt,false    ; Turn off the flag.
  631.     pop ax
  632.     jmp rskp        ; Return the character.
  633.  
  634. INCHR    ENDP
  635.  
  636.  
  637. ; Return next character in AL
  638. GETCHR  PROC
  639.  
  640.     push bx
  641.     mov bx,pktptr        ; Get the packet pointer.
  642.     mov al,[bx]        ; Get the char.
  643.     inc bx
  644.     mov pktptr,bx
  645.     pop bx            ; Restore BX.
  646.     cmp al,trans.reol    ; Is it the EOL char?
  647.     jne getcr2        ; If not return retskp.
  648.     ret            ; If so return failure.
  649.  
  650. getcr2:
  651. ;    jmp rskp
  652.  
  653. GETCHR  ENDP
  654.  
  655.  
  656. ; Jumping to this location is like retskp.  It assumes the instruction
  657. ;   after the call is a jmp addr.
  658.  
  659. RSKP    PROC    NEAR
  660.     pop bp
  661.     add bp,3
  662.     push bp
  663. ;    ret
  664. RSKP    ENDP
  665.  
  666. ; Jumping here is the same as a ret.
  667.  
  668. R    PROC    NEAR
  669.     ret
  670. R    ENDP
  671.  
  672. Code    ENDS
  673.  
  674.     END
  675. 
  676.